///////////////////// start to compute features ////////////////////////
	KALDI_VLOG(4) << "[5]:start to summarize all features";
	int32 num_not_detected = num_sub_words + num_del_words;

	while (num_not_detected > 0) {
		all_durlikes.push_back(kLowerBound);
		all_gops.push_back(kLowerBound);
		all_likelihoods.push_back(kLowerBound);
		num_not_detected--;
	}
	int32 num_not_detected_vowel = num_del_vowels + num_sub_vowels;
	int32 num_not_detected_const = num_del_consts + num_sub_consts;
	while (num_not_detected_const > 0)
	{
		all_consonants_gops.push_back(kLowerBound);
		num_not_detected_const--;
	}

	while (num_not_detected_vowel > 0)
	{
		all_vowels_gops.push_back(kLowerBound);
		num_not_detected_vowel--;
	}


	BaseFloat mean_durlike = 0.0; // stats from big data
	BaseFloat min_durlike = 0.0; //kLowerBound
	BaseFloat vowels_min_durlike = 0.0;
	BaseFloat consts_min_durlike = 0.0;
	//std::valarray<BaseFloat> fast_all_gops(std::initializer_list(all_gops));
	if (all_durlikes.size()) {
		mean_durlike = std::accumulate(all_durlikes.begin(), all_durlikes.end(),
			0.0f) / all_durlikes.size(); //mean
		min_durlike = *std::min_element(all_durlikes.begin(), all_durlikes.end());
	}

	BaseFloat var_durlike = BaseFloatVectorVar(all_durlikes, kUpperBound);
	BaseFloat var_gop = BaseFloatVectorVar(all_gops, kUpperBound);
	//BaseFloat vowel_gop_var = BaseFloatVectorVar(all_vowels_gops, kUpperBound);
	//BaseFloat const_gop_var = BaseFloatVectorVar(all_consonants_gops, kUpperBound);

	BaseFloat vowels_mean_durlike = kLowerBound; // stats from big data
	if (all_vowels_durlikes.size()) {
		vowels_mean_durlike = std::accumulate(all_vowels_durlikes.begin(),
			all_vowels_durlikes.end(), (num_sub_vowels + num_del_vowels)*kLowerBound) /
			(all_vowels_durlikes.size() + num_sub_vowels + num_del_vowels);
	}

	// not used
	BaseFloat vowels_mean_likelihood = kLowerBound;
	if (all_vowels_likelihoods.size()) {
		vowels_mean_likelihood = (
			std::accumulate(all_vowels_likelihoods.begin(), all_vowels_likelihoods.end(), 0.0f)) /
			all_vowels_likelihoods.size();
		vowels_min_durlike = *std::min_element(all_vowels_durlikes.begin(), all_vowels_durlikes.end());
	}

	if (all_consts_durlikes.size()) {
		consts_min_durlike = *std::min_element(all_consts_durlikes.begin(), all_consts_durlikes.end());
	}

	BaseFloat consonants_mean_likelihood = kLowerBound;
	if (all_consonants_likelihoods.size()) {
		consonants_mean_likelihood = (
			std::accumulate(all_consonants_likelihoods.begin(), all_consonants_likelihoods.end(), 0.0f))
			/ all_consonants_likelihoods.size();
	}



	KALDI_VLOG(4) << "[6]";

	BaseFloat min_likelihood = kLowerBound, max_likelihood = kLowerBound;
	if (all_likelihoods.size()) {
		min_likelihood = *std::min_element(all_likelihoods.begin(), all_likelihoods.end());
		max_likelihood = *std::max_element(all_likelihoods.begin(), all_likelihoods.end());
	}

	BaseFloat min_gop = 0.0, max_gop = 0.0;  // kLowerBound
	//BaseFloat min_gop = kLowerBound, max_gop = kLowerBound;  // kLowerBound
	BaseFloat vowel_min_gop = kLowerBound, vowel_max_gop = kLowerBound;
	BaseFloat const_min_gop = kLowerBound, const_max_gop = kLowerBound;
	if (all_gops.size() != 0) {

		auto min_gop_ptr = std::min_element(all_gops.begin(), all_gops.end());
		auto max_gop_ptr = std::max_element(all_gops.begin(), all_gops.end());
		min_gop = *min_gop_ptr;
		max_gop = *max_gop_ptr;
	}

	if (all_vowels_gops.size()) {
		vowel_min_gop = *std::min_element(all_vowels_gops.begin(), all_vowels_gops.end());
		vowel_max_gop = *std::max_element(all_vowels_gops.begin(), all_vowels_gops.end());
	}

	if (all_consonants_gops.size()) {
		const_min_gop = *std::min_element(all_consonants_gops.begin(), all_consonants_gops.end());
		const_max_gop = *std::max_element(all_consonants_gops.begin(), all_consonants_gops.end());
	}

	BaseFloat mean_likelihood = std::accumulate(all_likelihoods.begin(), all_likelihoods.end(), 0.0f);
	if (all_likelihoods.size()) {
		mean_likelihood = mean_likelihood / all_likelihoods.size(); //mean
	}

	BaseFloat mean_gop = std::accumulate(all_gops.begin(), all_gops.end(), 0.0f);
	if (all_gops.size()) {
		mean_gop = mean_gop / all_gops.size();
	}

	BaseFloat mean_vowel_gop = kLowerBound;
	if (all_vowels_gops.size()) {
		mean_vowel_gop = std::accumulate(all_vowels_gops.begin(), all_vowels_gops.end(),
			0.0f) / all_vowels_gops.size();
	}

	BaseFloat mean_consonant_gop = kLowerBound;
	if (all_consonants_gops.size()) {
		mean_consonant_gop =
			std::accumulate(all_consonants_gops.begin(), all_consonants_gops.end(),
				0.0f) / all_consonants_gops.size();
	}

	BaseFloat total_fillers_dur = bothsides_fillers_estimated_dur + insides_SPN_dur;
	BaseFloat total_sil_dur = 0;
	if ((duration_word - total_fillers_dur - dur_detected_words) > 0) {
		total_sil_dur = duration_word - total_fillers_dur - dur_detected_words;
	}


	// Not red calculation
	BaseFloat not_red_rate = 0.0;
	BaseFloat not_red_vowel_rate = 0.0;
	BaseFloat not_red_const_rate = 0.0;
	BaseFloat green_rate = 0.0;
	not_red_rate = (BaseFloat)std::count_if(all_gops.begin(), all_gops.end(), [](BaseFloat i) {return i >= std::atan(-4); }) / all_gops.size();
	not_red_vowel_rate = (BaseFloat)std::count_if(all_vowels_gops.begin(), all_vowels_gops.end(), [](BaseFloat i) {return i >= std::atan(-4); }) / all_vowels_gops.size();
	not_red_const_rate = (BaseFloat)std::count_if(all_consonants_gops.begin(), all_consonants_gops.end(), [](BaseFloat i) {return i >= std::atan(-4); }) / all_consonants_gops.size();
	green_rate = (BaseFloat)std::count_if(all_gops.begin(), all_gops.end(), [](BaseFloat i) {return i > std::atan(-1); }) / all_gops.size();
	// 0/1 features
	BaseFloat is_no_sil = (total_sil_dur > 0) ? 0 : 1;
	BaseFloat is_no_long_sil = (total_sil_dur >= 0.12) ? 0 : 1;
	BaseFloat is_no_red = (not_red_rate < 1) ? 0 : 1;
	BaseFloat is_90_no_red = (not_red_rate < 0.9) ? 0 : 1;
	BaseFloat is_all_vowel_detected = (detected_vowels_ratio < 1) ? 0 : 1;
	BaseFloat is_all_consonant_detected = (detected_consts_ratio < 1) ? 0 : 1;
	BaseFloat is_80_vowel_detected = (detected_vowels_ratio < 0.8) ? 0 : 1;
	BaseFloat is_80_consonant_detected = (detected_consts_ratio < 0.8) ? 0 : 1;

	KALDI_VLOG(4) << "[7]";

	//////////////////////////////////////////////////////////////////////////
	if (is_use_rule)
	{
		int det_idx = 0, notbad_idx = 0, good_idx = 0;

		if (detected_ratio >= 1.0) det_idx = 0;
		else if (detected_ratio >= 0.66) det_idx = 1;
		else if (detected_ratio >= 0.33) det_idx = 2;
		else det_idx = 3;

		if (not_red_rate >= 1.0) notbad_idx = 0;
		else if (not_red_rate >= 0.75) notbad_idx = 1;
		else if (not_red_rate >= 0.50) notbad_idx = 2;
		else if (not_red_rate >= 0.25) notbad_idx = 3;
		else notbad_idx = 4;

		if (green_rate >= 1.0) good_idx = 0;
		else if (green_rate >= 0.75) good_idx = 1;
		else if (green_rate >= 0.50) good_idx = 2;
		else if (green_rate >= 0.25) good_idx = 3;
		else good_idx = 4;

		BaseFloat rule_matrix[4][5][5] = {
			// det100%
			{{100, 95, 90, 90, 85},
			{-1, 85, 80, 75, 70},
			{-1, -1, 75, 70, 65},
			{-1, -1, -1, 65, 60},
			{-1, -1, -1, -1, 55}},
			// det66%+
			{{55, 50, 50, 45, 45},
			{-1, 50, 45, 45, 40},
			{-1, -1, 45, 40, 40},
			{-1, -1, -1, 40, 35},
			{-1, -1, -1, -1, 35}},
			// det33%+
			{{35, 30, 30, 25, 25},
			{-1, 30, 25, 25, 20},
			{-1, -1, 25, 20, 20},
			{-1, -1, -1, 20, 15},
			{-1, -1, -1, -1, 15}},
			// else
			{{10, 10, 5, 5, 0},
			{-1, 5, 5, 0, 0},
			{-1, -1, 0, 0, 0},
			{-1, -1, -1, 0, 0},
			{-1, -1, -1, -1, 0}}
		};

		BaseFloat base_score = rule_matrix[det_idx][notbad_idx][good_idx];
		BaseFloat gop_bonus = std::max(0.0f, std::min(5.0f, 5.0f * (1.0f - (mean_gop / kLowerBound))));
		BaseFloat silence_punishment = -std::max(0.0f, std::min(20.0f, 20.0f * total_sil_dur / duration_word));
		BaseFloat final_rule_score = base_score + gop_bonus + silence_punishment;
		rule_score = final_rule_score;
	}

	// [1]--->[6]
	//node_vec.push_back(min_gop);
	node_vec.push_back(mean_gop);
	node_vec.push_back(min_durlike);
	//node_vec.push_back(detected_time_ratio);
	//node_vec.push_back(detected_vowels_ratio);
	//node_vec.push_back(detected_consts_ratio);
	//node_vec.push_back(not_red_vowel_rate);
	//node_vec.push_back(not_red_const_rate);
	node_vec.push_back(is_no_long_sil);
	node_vec.push_back(green_rate);
	node_vec.push_back(is_90_no_red);
	node_vec.push_back(is_80_vowel_detected);
	node_vec.push_back(is_80_consonant_detected);
	/*
	node_vec.push_back(exp(-total_sil_dur / duration_word));
	node_vec.push_back(exp(-total_fillers_dur / duration_word));
	node_vec.push_back(detected_time_ratio);

	//node_vec.push_back(min_durlike);
	node_vec.push_back(vowels_min_durlike);
	node_vec.push_back(consts_min_durlike);
	node_vec.push_back(var_durlike);

	node_vec.push_back(mean_durlike);

	node_vec.push_back(vowel_min_gop);
	node_vec.push_back(const_min_gop);


	node_vec.push_back(var_gop);
	node_vec.push_back(mean_vowel_gop);
	node_vec.push_back(mean_consonant_gop);
	*/



	int32 class_label = m_Confidence->PredictWordScore(&node_vec);
	final_score = score_map[class_label];
	// Slightly adjust final score by Haoyu
	final_score += 5 * (1 - (mean_gop / kLowerBound));

	KALDI_VLOG(2) << "----------------------------------ORIG FINAL SCORE : " << final_score;
	if (is_use_rule)
	{
		KALDI_VLOG(2) << "----------------------------------RULE SCORE : " << rule_score;
		final_score = (rule_score + final_score) / 2;
		KALDI_VLOG(2) << "----------------------------------Fused SCORE : " << final_score;
		//		final_score = rule_score;
	}


	if (final_score > 100.0) {
		final_score = 100.0;
	}
	else {
		if (final_score < 0.0) {
			final_score = 0.0;
		}
	}